package com.shadow.demo.common.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;

/**
 * Jackson工具操作类.
 *
 * @author shadow
 */
@Slf4j
public final class JacksonUtils {

    private static final String ERROR_LOG = "json转换异常";

    /** jackson对象. **/
    private static final ObjectMapper MAPPER = new ObjectMapper()
            //序列化的时候序列对象的那些属性
            .setSerializationInclusion(JsonInclude.Include.ALWAYS)
            //反序列化时,遇到未知属性会不会报错：true - 遇到没有的属性就报错 false - 没有的属性不会管，不会报错
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            //如果是空对象的时候,不抛异常
            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
            // 允许出现单引号
            .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
            //修改序列化后日期格式
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            //处理不同的时区偏移格式
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .registerModule(new JavaTimeModule());

    private JacksonUtils() {
    }

    /**
     * 对象转json字符串.
     *
     * @param object 对象信息
     * @return java.lang.String
     **/
    public static String toJsonString(final Object object) {
        try {
            return MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            log.error(ERROR_LOG, e);
            return null;
        }
    }

    /**
     * json字符串转对象.
     *
     * @param jsonString json字符串
     * @param clazz 对象类
     * @param <T> 对象类型
     * @return T
     **/
    public static <T> T toObject(final String jsonString, final Class<T> clazz) {
        try {
            return MAPPER.readValue(jsonString, clazz);
        } catch (JsonProcessingException e) {
            log.error(ERROR_LOG, e);
            return null;
        }
    }

    /**
     * json字符串转泛型抽象对象，如List<>、Map<>等等.
     *
     * @param jsonString json字符串
     * @param type 集合类型
     * @param <T> 对象类型
     * @return T
     **/
    public static <T> T toTypeObject(final String jsonString, final TypeReference<T> type) {
        try {
            return MAPPER.readValue(jsonString, type);
        } catch (JsonProcessingException e) {
            log.error(ERROR_LOG, e);
            return null;
        }
    }
}
